;; **********************************************************************
;;                           circuitgui.clp
;;
;; For the course Reasoning with Computer Support: an example 
;; illustrating the use of Java guis 
;;
;; Arjen Hommersom, October 2010
;;
;; **********************************************************************

(provide create-gui)

;; ******************************
;; Declarations

(import jess.awt.*)
(import javax.swing.*)
(import java.awt.GridLayout)
(import java.util.Vector)

;; ******************************
;; DEFTEMPLATES

(deftemplate GUIinputs
	(slot in1)
	(slot in2)
	(slot in3))

;; ******************************
;; DEFGLOBALS

(defglobal ?*frame* = 0)
(defglobal ?*input1* = 0)
(defglobal ?*input1* = 0)
(defglobal ?*input1* = 0)
(defglobal ?*output1* = 0)
(defglobal ?*output2* = 0)

;; ******************************
;; DEFFUNCTIONS

(deffunction fetchint (?name)
    (bind ?f (fetch ?name))
    (if (eq ?f nil) then
	(return "null")
    else
	(return ((new Integer ?f) toString))))

(deffunction run-circuit (?evt)
    ;; add inputs to the system
    (assert (GUIinputs (in1 (?*input1* getSelectedItem)) 
                       (in2 (?*input2* getSelectedItem)) 
                       (in3 (?*input3* getSelectedItem)))) 
    ;; apply rules
    (run)
    ;; retrieve output value (defined by the rules)
    (set ?*output1* text (fetchint "O1"))
    (set ?*output2* text (fetchint "O2")))

(deffunction frame-handler (?evt)
    (if (= (?evt getID) (get-member ?evt WINDOW_CLOSING)) then 
        (call (get ?evt source) dispose)))

(deffunction dispose-frame (?evt) (?*frame* dispose))

(deffunction create-gui ()
    ;; create the frame, a button and an output label
    (bind ?*frame* (new JFrame "Circuit"))
    (bind ?run (new JButton "Run circuit"))
    (bind ?exit (new JButton "Exit"))

    ;; create comboboxes for input
    (bind ?binaryvalues (new Vector))
    (?binaryvalues add 0)
    (?binaryvalues add 1)
    (bind ?*input1* (new JComboBox ?binaryvalues))
    (bind ?*input2* (new JComboBox ?binaryvalues))
    (bind ?*input3* (new JComboBox ?binaryvalues))
    (bind ?*output1* (new JLabel "No output"))
    (bind ?*output2* (new JLabel "No output"))

    ;; set a layout on the content pane
    (bind ?pane (?*frame* getContentPane))
    (bind ?layout (new GridLayout 6 2))
    (?layout setHgap 50)
    (?layout setVgap 5)
    (?pane setLayout ?layout)

    ;; add widgets to the frame
    (?pane add (new JLabel " Input 1"))
    (?pane add ?*input1*)
    (?pane add (new JLabel " Input 2"))
    (?pane add ?*input2*)
    (?pane add (new JLabel " Input 3"))
    (?pane add ?*input3*)
    (?pane add (new JLabel " Output 1"))
    (?pane add ?*output1*)
    (?pane add (new JLabel " Output 2"))
    (?pane add ?*output2*)
    (?pane add ?run)
    (?pane add ?exit)

    ;; add behaviours
    (?run addActionListener (new ActionListener run-circuit (engine)))
    (?exit addActionListener (new ActionListener dispose-frame (engine)))
    (?*frame* addWindowListener (new WindowListener frame-handler (engine)))

    ;; show the frame
    (?*frame* pack)
    (?*frame* setLocation 300 300)
    (set ?*frame* visible TRUE))

